<template>
  <div ref="container" class="container" @wheel="onWheel">
    <canvas ref="backgroundCanvas" class="background-canvas"></canvas>
    <div style="position: absolute" class="target-box"></div>

    <div class="image-box" :style="imageBoxStyle" @mousedown="onMouseDown" @transitionend="onTransitionEnd">
      <div :style="imageStyle1" class="overlay-image"></div>
      <div :style="imageStyle2" class="overlay-image"></div>
      <div :style="imageStyle3" class="overlay-image"></div>
    </div>
  </div>
</template>
 
<script>
import { ref, computed, onMounted, onBeforeUnmount } from "vue";
import { useStore } from "vuex";

export default {
  name: "PhotoMain",
  props: {
    widthPercentage: {
      type: Number,
      default: null,
    },
    heightPercentage: {
      type: Number,
      default: null,
    },
    selectedIndex: {
      type: Number,
      default: null,
    },
    value0: {
      type: Number,
      default: 100,
    },
    value1: {
      type: Number,
      default: 0,
    },
    value2: {
      type: Number,
      default: 5,
    },
    shrinkImage: {
    type: Function,
    default: () => {}
  }
  },
  emits: [
    "update:widthPercentage",
    "update:heightPercentage",
    "update:selectedIndex",
  ],
  watch: {
    widthPercentage(newVal) {
      this.centerImageToPercentage();
    },
    heightPercentage(newVal) {
      this.centerImageToPercentage();
    },
    selectedIndex(newVal) {
      this.centerImageToPercentage();
    },
  },
  setup(props, { emit }) {
    const store = useStore();
    const container = ref(null);
    const scale = ref(1);
    const posX = ref(0);
    const posY = ref(0);
    const isDragging = ref(false);
    const startX = ref(0);
    const startY = ref(0);
    const centerX = ref(0);
    const centerY = ref(0);
    const isTransitioning = ref(false);

    const leftImage = computed(() => store.getters.leftImage);
    const rightImage = computed(() => store.getters.rightImage);
    const predictionImage = computed(() => store.getters.photoData.prediction);

    const shrinkImage = () => {
      // isTransitioning.value = false; // 结束过渡状态
      // isTransitioning.value = true;
      // scale.value = Math.max(0.1, scale.value - 0.1 * 14.85); 
      scale.value = 1.085; 
    };

    const imageBoxStyle = computed(() => ({
      transform: `translate(${posX.value}px, ${posY.value}px) scale(${scale.value})`,
      position: "relative",
      width: "100%",
      height: "100%",
      transition: isTransitioning.value ? "transform 1s" : "none",
    }));

    const imageStyle1 = computed(() => ({
      backgroundImage: leftImage.value ? `url(${leftImage.value})` : "",
      opacity: props.value0 / 100,
    }));

    const imageStyle2 = computed(() => ({
      backgroundImage: leftImage.value ? `url(${rightImage.value})` : "",
      opacity: props.value1 / 100,
    }));

    const imageStyle3 = computed(() => ({
      backgroundImage: `url(${predictionImage.value})`,
      opacity: props.value2 / 100,
    }));

    const onWheel = (event) => {
      event.preventDefault();
      if (event.deltaY < 0) {
        scale.value += 0.1;
      } else {
        scale.value = Math.max(0.1, scale.value - 0.1);
      }
      resetProps();
    };

    const onMouseDown = (event) => {
      isDragging.value = true;
      startX.value = event.clientX - posX.value;
      startY.value = event.clientY - posY.value;
      document.addEventListener("mousemove", onMouseMove);
      document.addEventListener("mouseup", onMouseUp);
    };

    const onMouseMove = (event) => {
      if (!isDragging.value) return;
      posX.value = event.clientX - startX.value;
      posY.value = event.clientY - startY.value;
    };

    const onMouseUp = () => {
      isDragging.value = false;
      document.removeEventListener("mousemove", onMouseMove);
      document.removeEventListener("mouseup", onMouseUp);
      resetProps();
    };

    const onTransitionEnd = () => {
      isTransitioning.value = false;
      resetProps();
    };

    const resetProps = () => {
      emit("update:widthPercentage", null);
      emit("update:heightPercentage", null);
      emit("update:selectedIndex", null);
    };

    const centerImageToPercentage = () => {
      if (
        props.widthPercentage !== null &&
        props.heightPercentage !== null &&
        props.selectedIndex !== null
      ) {
        const containerWidth = container.value.clientWidth;
        const containerHeight = container.value.clientHeight;
        const imageBox = container.value.querySelector(".image-box");
        const imageBoxWidth = imageBox.clientWidth;
        const imageBoxHeight = imageBox.clientHeight;

        const targetPixelX = imageBoxWidth * props.widthPercentage;
        const targetPixelY = imageBoxHeight * props.heightPercentage;

        const targetBox = container.value.querySelector(".target-box");
        const targetBoxRect = targetBox.getBoundingClientRect();
        const containerRect = container.value.getBoundingClientRect();
        const targetCenterX =
          targetBoxRect.left + targetBoxRect.width / 2 - containerRect.left;
        const targetCenterY =
          targetBoxRect.top + targetBoxRect.height / 2 - containerRect.top;

        posX.value = targetCenterX - targetPixelX * scale.value;
        posY.value = targetCenterY - targetPixelY * scale.value;

        isTransitioning.value = true;
      }
    };

    const updateCenterPosition = () => {
      const containerWidth = container.value.clientWidth;
      const containerHeight = container.value.clientHeight;
      centerX.value = containerWidth / 2;
      centerY.value = containerHeight / 2;
      shrinkImage();
    };

    const initDynamicBackground = () => {
      const canvas = container.value.querySelector(".background-canvas");
      const ctx = canvas.getContext("2d");
      let num = 100;
      let colorLine = "#7AA5B6";
      let myWidth = (canvas.width = container.value.clientWidth);
      let myHeight = (canvas.height = container.value.clientHeight);
      let allCircle = [];
      let newCircleArray, ani;

      for (let i = 0; i < num; i++) {
        let x = Math.random() * myWidth;
        let y = Math.random() * myHeight;
        let offX = Math.random() * 2 - 1;
        let offY = Math.random() * 2 - 1;
        allCircle.push({
          x: x,
          y: y,
          offX: offX * 0.5,
          offY: offY * 0.5,
          maxLen: 8000,
        });
        drawCircle(x, y, 0.5);
      }

      function drawCircle(x, y, r) {
        ctx.save();
        ctx.beginPath();
        ctx.arc(x, y, r, 0, Math.PI * 2);
        ctx.closePath();
        ctx.fillStyle = colorLine;
        ctx.fill();
        ctx.restore();
      }

      function initDraw() {
        for (let i = 0; i < num; i++) {
          for (let j = 0; j < num; j++) {
            let xc = allCircle[i].x - allCircle[j].x;
            let yc = allCircle[i].y - allCircle[j].y;
            let length = xc * xc + yc * yc;
            if (length < allCircle[i].maxLen) {
              let lineA = 1 - length / allCircle[i].maxLen;
              ctx.save();
              ctx.beginPath();
              ctx.moveTo(allCircle[i].x, allCircle[i].y);
              ctx.lineTo(allCircle[j].x, allCircle[j].y);
              ctx.closePath();
              ctx.strokeStyle = colorLine;
              ctx.strokeStyle = "rgba(122,165,182," + lineA + ")";
              ctx.strokeWidth = 1;
              ctx.stroke();
              ctx.restore();
            }
          }
        }
      }

      function moveCircle() {
        ctx.clearRect(0, 0, myWidth, myHeight);
        for (let i = 0; i < num; i++) {
          allCircle[i].x += allCircle[i].offX;
          allCircle[i].y += allCircle[i].offY;
          if (allCircle[i].x > myWidth || allCircle[i].x < 0) {
            allCircle[i].offX = -allCircle[i].offX;
          }
          if (allCircle[i].y > myHeight || allCircle[i].y < 0) {
            allCircle[i].offY = -allCircle[i].offY;
          }
        }
        initDraw();
        let n = () => {
          ani(moveCircle);
        };
        setTimeout(n, 1000 / 60);
      }

      ani =
        window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        function (callback) {
          setTimeout(callback, 1000 / 60);
        };

      ani(moveCircle);
    };

    onMounted(() => {
      const containerWidth = container.value.clientWidth;
      const containerHeight = container.value.clientHeight;
      const image = new Image();
      image.src = leftImage.value;
      image.onload = () => {
        const imageWidth = image.width;
        const imageHeight = image.height;
        const scaleValue = Math.min(
          containerWidth / imageWidth,
          containerHeight / imageHeight
        );
        scale.value = scaleValue;
        posX.value = (containerWidth - imageWidth * scaleValue) / 2;
        posY.value = (containerHeight - imageHeight * scaleValue) / 2;
        updateCenterPosition();
      };

      initDynamicBackground();
      window.addEventListener("resize", updateCenterPosition);
    });

    onBeforeUnmount(() => {
      window.removeEventListener("resize", updateCenterPosition);
    });

    return {
      container,
      imageBoxStyle,
      imageStyle1,
      imageStyle2,
      imageStyle3,
      onWheel,
      onMouseDown,
      onMouseMove,
      onMouseUp,
      centerImageToPercentage,
      updateCenterPosition,
      onTransitionEnd,
      shrinkImage,
    };
  },
};
</script>

<style scoped>
.container {
  aspect-ratio: 1 / 1;
  padding: 0;
  position: relative;
  overflow: hidden;
  background-color: rgb(5, 5, 5);
}

.background-canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
}

.image-box {
  width: 100%;
  height: 100%;
  cursor: grab;
  z-index: 1;
  position: relative;
}

.image-box:active {
  cursor: grabbing;
}

.overlay-image {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}
</style>
